package com.ca.ridersclubapplication.request;

import android.app.Activity;

import androidx.annotation.NonNull;

import com.ca.ridersclubapplication.data.DataHandler;
import com.ca.ridersclubapplication.request.dto.AccountCardDto;
import com.ca.ridersclubapplication.request.dto.AccountDto;
import com.ca.ridersclubapplication.data.entity.BooleanEntity;
import com.ca.ridersclubapplication.data.entity.ClubClassify;
import com.ca.ridersclubapplication.data.entity.ListEntity;
import com.ca.ridersclubapplication.data.entity.LongEntity;
import com.ca.ridersclubapplication.data.entity.Token;
import com.ca.ridersclubapplication.request.dto.ClubDto;
import com.ca.ridersclubapplication.request.dto.ClubItemDto;
import com.ca.ridersclubapplication.request.dto.Result;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Query;

public class ClubRequester {

    public static final String URL = "club/";
    public static final ClubAPI api;

    static {
        api = new Retrofit.Builder()
                .baseUrl(Config.BASE_URL + URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(ClubAPI.class);
    }

    public interface ClubAPI {

        @GET("getById")
        Call<Result<ClubDto>> getClubById(@Query("clubId") Long clubId);

        @GET("getByName")
        Call<Result<List<ClubDto>>> getClubByName(@Query("name") String name);

        @GET("all")
        Call<Result<List<ClubDto>>> getAllClubs();

        @GET("get/follow")
        Call<Result<List<ClubDto>>> getFollowClubs(@Query("accountId") Long accountId);

        @POST("add/follow")
        @FormUrlEncoded
        Call<Result<String>> addFollow(
                @Field("clubId") Long clubId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("delete/follow")
        @FormUrlEncoded
        Call<Result<String>> deleteFollow(
                @Field("clubId") Long clubId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("isFollow")
        Call<Result<Boolean>> isFollow(
                @Query("clubId") Long clubId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("fansCount")
        Call<Result<Long>> getFansCount(@Query("clubId") Long clubId);

        @GET("classify/all")
        Call<Result<List<ClubClassify>>> getAllClassify();

        @GET("getByClassify")
        Call<Result<List<ClubDto>>> getByClassify(@Query("classify") String classify);

        @GET("listFans")
        Call<Result<List<AccountCardDto>>> listFans(@Query("clubId") Long clubId);

        @POST("addWant")
        @FormUrlEncoded
        Call<Result<String>> addWant(
                @Field("clubId") Long clubId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("deleteWant")
        @FormUrlEncoded
        Call<Result<String>> deleteWant(
                @Field("clubId") Long clubId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("isWant")
        Call<Result<Boolean>> isWant(
                @Query("clubId") Long clubId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("postGrade")
        @FormUrlEncoded
        Call<Result<String>> postGrade(
                @Field("clubId") Long clubId,
                @Field("grade") Long grade,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("isPostGrade")
        Call<Result<Boolean>> isPostGrade(
                @Query("clubId") Long clubId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("list3FansId")
        Call<Result<List<Long>>> list3FansId(@Query("clubId") Long clubId);

        @GET("listBannerClubId")
        Call<Result<List<Long>>> listBannerClubId();

        @GET("listClubByClassify")
        Call<Result<List<ClubItemDto>>> listClubByClassify(@Query("classify") String classify);
    }

    public static void getClubById(Activity activity, Long clubId, AfterExecutor<ClubDto> executor) {
        api.getClubById(clubId).enqueue(new APICallback<>(activity, executor));
    }

    public static void getClubByName(Activity activity, String name, AfterExecutor<List<ClubDto>> executor) {
        api.getClubByName(name)
                .enqueue(new APICallback<List<ClubDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<ClubDto>>> call, @NonNull Response<Result<List<ClubDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>("ClubListByName:" + name, getData()));
                        }
                    }
                });
    }

    public static void getClubByClassify(Activity activity, String classify, AfterExecutor<List<ClubDto>> executor) {
        api.getByClassify(classify)
                .enqueue(new APICallback<List<ClubDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<ClubDto>>> call, @NonNull Response<Result<List<ClubDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>("ClubListByClassify:" + classify, getData()));
                        }
                    }
                });
    }

    public static void listAllClub(Activity activity, AfterExecutor<List<ClubDto>> executor) {
        api.getAllClubs()
                .enqueue(new APICallback<List<ClubDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<ClubDto>>> call, @NonNull Response<Result<List<ClubDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>("ClubList:all", getData()));
                        }
                    }
                });
    }

    public static void listFollowClub(Activity activity, Long accountId, AfterExecutor<List<ClubDto>> executor) {
        api.getFollowClubs(accountId)
                .enqueue(new APICallback<List<ClubDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<ClubDto>>> call, @NonNull Response<Result<List<ClubDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>("ClubFollowList:" + accountId, getData()));
                        }
                    }
                });
    }

    public static void addFollow(Activity activity, Long clubId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.addFollow(clubId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<String>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<String>> call, @NonNull Response<Result<String>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            //  添加关注成功后，将是否关注数据设为true
                            DataHandler.putData(new BooleanEntity("ClubIsFollow:" + clubId, true));
                            DataHandler.putData(new BooleanEntity("HasNewFollowClub", true));
                        }
                    }
                });
    }

    public static void deleteFollow(Activity activity, Long clubId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.deleteFollow(clubId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<String>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<String>> call, @NonNull Response<Result<String>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            //  取消关注成功后，将是否关注数据设为false
                            DataHandler.putData(new BooleanEntity("ClubIsFollow:" + clubId, false));
                            DataHandler.putData(new BooleanEntity("HasNewFollowClub", true));
                        }
                    }
                });
    }

    public static void isFollow(Activity activity, Long clubId, AfterExecutor<Boolean> executor) {
        Token token = DataHandler.getToken(activity);
        api.isFollow(clubId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<Boolean>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Boolean>> call, @NonNull Response<Result<Boolean>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new BooleanEntity("ClubIsFollow:" + token.getId(), getData()));
                        }
                    }
                });
    }

    public static void getFansCount(Activity activity, Long clubId, AfterExecutor<Long> executor) {
        api.getFansCount(clubId)
                .enqueue(new APICallback<Long>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Long>> call, @NonNull Response<Result<Long>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new LongEntity("ClubFansCount:" + clubId, getData()));
                        }
                    }
                });
    }

    public static void listAllClassify(Activity activity, AfterExecutor<List<ClubClassify>> executor) {
        api.getAllClassify()
                .enqueue(new APICallback<List<ClubClassify>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<ClubClassify>>> call, @NonNull Response<Result<List<ClubClassify>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>("ClubClassify:all", getData()));
                        }
                    }
                });
    }

    public static void listFans(Activity activity, Long clubId, AfterExecutor<List<AccountCardDto>> executor) {
        api.listFans(clubId)
                .enqueue(new APICallback<List<AccountCardDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<AccountCardDto>>> call, @NonNull Response<Result<List<AccountCardDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>("ClubFansList:" + clubId, getData()));
                        }
                    }
                });
    }

    public static void addWant(Activity activity, Long clubId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.addWant(clubId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void deleteWant(Activity activity, Long clubId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.deleteWant(clubId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void postGrade(Activity activity, Long clubId, Long grade, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.postGrade(clubId, grade, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void list3FansId(Activity activity, Long clubId, AfterExecutor<List<Long>> executor) {
        api.list3FansId(clubId)
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void isWant(Activity activity, Long clubId, AfterExecutor<Boolean> executor) {
        Token token = DataHandler.getToken(activity);
        api.isWant(clubId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void isPostGrade(Activity activity, Long clubId, AfterExecutor<Boolean> executor) {
        Token token = DataHandler.getToken(activity);
        api.isPostGrade(clubId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void listBannerClubId(Activity activity, AfterExecutor<List<Long>> executor) {
        api.listBannerClubId().enqueue(new APICallback<>(activity, executor));
    }

    public static void listClubByClassify(Activity activity, String classify, AfterExecutor<List<ClubItemDto>> executor) {
        api.listClubByClassify(classify)
                .enqueue(new APICallback<>(activity, executor));
    }
}
